const tween = {
    linear: function( t, b, c, d ){
        return c * t / d + b; 
    },
    easeIn: function( t, b, c, d ){
        return c * ( t /= d ) * t + b;
    },
    strongEaseIn: function(t, b, c, d){
        return c * ( t /= d ) * t * t * t
    },
    strongEaseOut: function(t, b, c, d) {
        return c * ( ( t = t / d - 1) * t * t * t * t + 1) + b;
    },
    sineaseIn: function( t, b, c, d ){
        return c * ( t /= d) * t * t + b; 
    },
    sineaseOut: function(t,b,c,d){
        return c * ( ( t = t / d - 1) * t * t + 1) + b;
    }
}

// const Animate = function (dom) {
//     this.dom = dom
//     this.startTime = 0
//     this.startPorps = 0
//     this.endPorps = 0
//     this.propertyName = null
//     this.easing = null
//     this.duration = null
// }

class Animate {
    constructor(dom) {
        this.dom = dom
        this.startTime = 0
        this.startPorops = 0
        this.endProps = 0
        this.propertyName = null
        this.easing = null
        this.duration = null
    }
    // start
    start(propertyName, endProps, duration, easing) {
        this.startTime = + new Date
        this.startPorops = this.dom.getBoundingClientRect()[propertyName]
        this.propertyName = propertyName
        this.endProps = endProps
        this.duration = duration
        this.easing = tween[easing]

        const timeId = setInterval(() => {
            if (this.step() === false) {
                clearInterval(timeId)
            }
        }, 20)
    }

    // step
    step () {
        const t = +new Date
        if (t >= this.startTime + this.duration) {
            this.update(this.endProps)
            return false
        }

        const pos = this.easing(t - this.startTime, this.startPorops, this.endProps - this.startPorops, this.duration)
        this.update(pos)
    }
    // update
    update (pos) {
        this.dom.style[this.propertyName] = pos + 'px'
    }
}